package com.longtop.framework.common;

import java.text.MessageFormat;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import com.longtop.intelliweb.common.Log;

/**
 * 资源信息管理类。
 * 
 * @author 胡砥峰
 *
 */
public class Message {

	private static final Log log = Log.getLogger(Message.class);

	/* 资源配置文件放置在src/config/common/applicationMessage_zh.properties */
	private static final String DEAULT_RESOURCE_FILE = "config.common.applicationMessage";

	private static Map bundleLocaleCache = new HashMap();

	/**
	 * 根据资源名称取得资源信息
	 * 
	 * @param name
	 * @return string
	 */
	public static String getMessage(String name) {
		return getMessage(DEAULT_RESOURCE_FILE, name, Locale.getDefault());
	}

	/**
	 * 根据资源名称及资源信息参数取得资源信息
	 * 
	 * @param name
	 * @param arguments
	 * @return string
	 */
	public static String getMessage(String name, Object[] arguments) {
		return getMessage(DEAULT_RESOURCE_FILE, name, arguments);
	}

	/**
	 * 根据资源名称及资源信息参数取得资源信息
	 * 
	 * @param name
	 * @param argument
	 * @return string
	 */
	public static String getMessage(String name, String argument) {
		return getMessage(DEAULT_RESOURCE_FILE, name, new Object[] { argument });
	}

	/**
	 * 根据locale，信息资源文件取得信息
	 * 
	 * @param resource
	 *            信息资源文件，如: exampleMessage
	 * @param name
	 *            信息key
	 * @param locale
	 *            如：zh_CN等对应的Locale
	 * @return 信息值
	 */
	public static String getMessage(String resource, String name, Locale locale) {
		if (resource == null || resource.length() <= 0)
			return "";
		if (name == null || name.length() <= 0)
			return "";

		ResourceBundle bundle = getResourceBundle(resource, locale);
		if (bundle == null)
			return "";

		String value = null;
		try {
			value = bundle.getString(name);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return value == null ? "" : value.trim();
	}

	/**
	 * 取得默认local的message
	 * 
	 * @param resource
	 * @param name
	 * @param arguments
	 * @return String
	 */
	public static String getMessage(String resource, String name, Object[] arguments) {
		return getMessage(resource, name, arguments, Locale.getDefault());
	}

	/**
	 * 根据locale，信息资源文件取得信息
	 * 
	 * @param resource
	 *            信息资源文件，如: exampleMessage
	 * @param name
	 *            信息key
	 * @param arguments
	 *            信息体包含的变量值
	 * @param locale
	 *            如：zh_CN等对应的Locale
	 * @return 信息值
	 */
	public static String getMessage(String resource, String name, Object[] arguments, Locale locale) {
		String value = getMessage(resource, name, locale);

		if (value == null || value.length() == 0) {
			return "";
		} else {
			if (arguments != null && arguments.length > 0) {
				value = MessageFormat.format(value, arguments);
			}
			return value;
		}
	}

	/**
	 * 取得<tt>ResourceBundle</tt>
	 */
	public static ResourceBundle getResourceBundle(String resource, Locale locale) {
		Map bundleMap = getResourceBundleMap(resource, locale);
		if (bundleMap == null) {
			return null;
		}
		return (ResourceBundle) bundleMap.get("_RESOURCE_BUNDLE_");
	}

	/**
	 * 返回以Map形式保存的resources
	 */
	public static Map getResourceBundleMap(String resource, Locale locale) {
		if (locale == null) {
			throw new IllegalArgumentException("Locale cannot be null");
		}

		String resourceCacheKey = resource + "_" + locale.toString();
		Map bundleMap = (Map) bundleLocaleCache.get(resourceCacheKey);

		if (bundleMap == null) {
			ResourceBundle bundle = getBaseResourceBundle(resource, locale);
			bundleMap = resourceBundleToMap(bundle);
			if (bundleMap != null) {
				bundleLocaleCache.put(resourceCacheKey, bundleMap);
			}
		}
		return bundleMap;
	}

	protected static ResourceBundle getBaseResourceBundle(String resource, Locale locale) {
		if (resource == null || resource.length() <= 0)
			return null;
		if (locale == null)
			locale = Locale.getDefault();

		ClassLoader loader = Thread.currentThread().getContextClassLoader();
		ResourceBundle bundle = null;
		try {
			bundle = ResourceBundle.getBundle(resource, locale, loader);
		} catch (MissingResourceException e) {
			log.logError("Could not find resource: " + resource + " for locale " + locale.toString() + ": " + e.toString());
			return null;
		}
		if (bundle == null) {
			log.logError("Could not find resource: " + resource + " for locale " + locale.toString());
			return null;
		}

		return bundle;
	}

	protected static Map resourceBundleToMap(ResourceBundle bundle) {
		if (bundle == null) {
			return new HashMap();
		}
		// NOTE: this should return all keys, including keys from parent
		// ResourceBundles, if not then something else must be done here...
		Enumeration keyNum = bundle.getKeys();
		Map resourceBundleMap = new HashMap();
		while (keyNum.hasMoreElements()) {
			String key = (String) keyNum.nextElement();
			// resourceBundleMap.put(key, bundle.getObject(key));
			Object value = bundle.getObject(key);
			resourceBundleMap.put(key, value);
		}
		resourceBundleMap.put("_RESOURCE_BUNDLE_", bundle);
		return resourceBundleMap;
	}
}
